package com.ruoyi.central.publisher;

import com.ruoyi.central.domain.TopCentralArtProcess;
import com.ruoyi.central.publisher.event.ArtProcessEvent;
import com.ruoyi.common.core.domain.BaseEvent;
import com.ruoyi.common.enums.SignEnum;
import com.ruoyi.common.utils.spring.SpringUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collection;

/**
 * @Classname publisherUtils
 * @Author: sunluquan
 * @Date: 2022/5/18 10:38
 * @Description TODO
 */
public class PublisherUtils {

    /**
     * 发布集合事件
     * @param baseEventClass 事件封装对象
     * @param ts 事件数据源
     * @param signEnum 事件标签
     * @param operationType 操作类型标识：false 手动触发 ，true 自动触发
     * @param <T>
     * @return
     */
    public static <T> void publishEvent(Class<?extends BaseEvent<T>> baseEventClass, Collection<T> ts, SignEnum signEnum, boolean operationType){

        Constructor<? extends BaseEvent<T>> constructor = getConstructor(baseEventClass,Collection.class,SignEnum.class,boolean.class);

        SpringUtils.getApplicationContext().publishEvent(initialize(constructor,ts,signEnum,operationType));
    }
    public static <T> void publishEvent(Class<? extends BaseEvent<T>> baseEventClass, Collection<T> ts,SignEnum signEnum){
        publishEvent(baseEventClass,ts,signEnum,false);
    }

    /**
     * 发布对象 事件
     * @param baseEventClass
     * @param t
     * @param signEnum
     * @param operationType
     * @param <T>
     */
    public static <T> void publishEvent(Class<? extends BaseEvent<T>> baseEventClass, T t, SignEnum signEnum, boolean operationType){
        Constructor<? extends BaseEvent<T>> constructor = getConstructor(baseEventClass,t.getClass(),SignEnum.class,boolean.class);

        SpringUtils.getApplicationContext().publishEvent(initialize(constructor,t,signEnum,operationType));
    }
    public static <T> void publishEvent(Class<? extends BaseEvent<T>> baseEventClass, T t, SignEnum signEnum){

        publishEvent(baseEventClass,t,signEnum,false);
    }

    /**
     * 获取发布事件的构造函数
     * @param baseEventClass
     * @param parameterTypes
     * @param <T>
     * @return
     */
    private static <T> Constructor<? extends BaseEvent<T>> getConstructor(Class<?extends BaseEvent<T>> baseEventClass,Class<?>... parameterTypes){
        try {
            return baseEventClass.getDeclaredConstructor(parameterTypes);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 实例化事件对象
     * @param constructor
     * @param args
     * @param <T>
     * @return
     */
    private static <T>  BaseEvent<T> initialize(Constructor<? extends BaseEvent<T>> constructor , Object ... args){
        try {
            return constructor.newInstance(args);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {


        Constructor<?>[] constructors = ArtProcessEvent.class.getConstructors();
        Arrays.stream(constructors).forEach(constructor -> {
            System.out.println("constructor:"+Arrays.toString(constructor.getParameterTypes()));
        });

        Constructor<? extends BaseEvent<TopCentralArtProcess>> constructor =
                getConstructor(ArtProcessEvent.class, Collection.class, SignEnum.class, boolean.class);

        System.out.println(constructor);
    }

}
